#include "doca_dma_common.h"
// #include "dpdk/doca_dpdk.h"
doca_error_t Dma_create(struct dma_handler * dma, struct dma_config * cfg, int mmap_type) {
  doca_error_t status = DOCA_SUCCESS;

  status = init_doca_device(const_cast<char*> (cfg->nic_pcie_addr.data() ), &dma->dev);
  if (status != DOCA_SUCCESS) {
    LOG(ERROR) << "Function init_doca_device returned " << doca_error_get_descr(status)
      << ", nic_pcie_addr=" << cfg->nic_pcie_addr;
    return status;
  }

  status = doca_pe_create(&dma->pe);
  if (status != DOCA_SUCCESS) {
    LOG(ERROR) << "Unable to create pe queue: " << doca_error_get_descr(status);
    return status;
  }

  status = doca_dma_create(dma->dev, &dma->dma);
  if (status != DOCA_SUCCESS) {
    LOG(ERROR) << "Failed to create DMA context: " << doca_error_get_descr(status);
    goto destroy_pe;
  }

  dma->ctx = doca_dma_as_ctx(dma->dma);
  
  if (mmap_type == 1) {  
    status = doca_ctx_set_user_data(dma->ctx, cfg->ctx_user_data);
    if (status != DOCA_SUCCESS) {
        LOG(ERROR) << "Failed doca_ctx_set_user_data: %s", doca_error_get_descr(status);
        goto destroy_dma;
    }
  }

  status = doca_pe_connect_ctx(dma->pe, dma->ctx);
  if (status != DOCA_SUCCESS) {
    LOG(ERROR) << "Failed doca_pe_connect_ctx: %s", doca_error_get_descr(status);
    goto destroy_dma;
  }

  if (mmap_type == 1) {
    status = doca_dma_task_memcpy_set_conf(dma->dma, cfg->complet_cb, cfg->error_cb,
                                            cfg->task_num);
    if (status != DOCA_SUCCESS) {
        LOG(ERROR) << "Failed to set configurations for DMA memcpy task: %s", doca_error_get_descr(status);
        goto destroy_dma;
    }
  }

  status = doca_ctx_start(dma->ctx);
  if (status != DOCA_SUCCESS) {
    LOG(ERROR) << "Failed to initialize dma ctx: Unable to start dma context: %s",
        doca_error_get_descr(status);
    goto destroy_dma;
  }

  return DOCA_SUCCESS;

destroy_dma:
  doca_dma_destroy(dma->dma);

destroy_pe:
  doca_pe_destroy(dma->pe);

  return status;
}